package mgr

import (
	"idle/internal/game/attr"
	"idle/internal/game/attr/cal"
	"idle/internal/game/equip"
	"idle/internal/game/hero"
	"sync"
)

var attrCalMgrInstance *attrCalMgr
var attrCalMgrOnce sync.Once

type attrCalMgr struct {
	AttrCalList []cal.IHeroAttrCal
}

func GetAttrCalMgr() *attrCalMgr {
	attrCalMgrOnce.Do(func() {
		attrCalMgrInstance = &attrCalMgr{
			AttrCalList: make([]cal.IHeroAttrCal, 0),
		}

	})
	return attrCalMgrInstance
}

func init() {
	GetAttrCalMgr().registerAttrCal(&cal.HpAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.ManaAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.DamageAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.AttAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.BlockAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.DefAttrCal{})
	GetAttrCalMgr().registerAttrCal(&cal.MagicDamageBonusAttrCal{})

}

func (m *attrCalMgr) registerAttrCal(c cal.IHeroAttrCal) {
	attrCalMgrInstance.AttrCalList = append(attrCalMgrInstance.AttrCalList, c)
}

func (m *attrCalMgr) CalHeroAllAttr(h *hero.Hero) {
	for _, attrCal := range m.AttrCalList {
		attrCal.Cal(h)
	}
}

func (m *attrCalMgr) CalEquipAttr(h *hero.Hero, eq *equip.Equip, wear bool) {
	for _, affix := range eq.AffixList {
		switch affix.Typ {
		case equip.BaseAttr:
			if len(affix.Values) != 2 {
				return
			}
			AttrType := attr.Attribute(affix.Values[0])
			AttrValue := affix.Values[1]
			oldValue := h.GetAttr(AttrType)
			newValue := 0
			if wear {
				newValue = oldValue + AttrValue
			} else {
				newValue = oldValue - AttrValue
			}
			h.SetAttr(AttrType, newValue)
		}
	}
	m.CalHeroAllAttr(h)
}
